<?php
/**
 * 封装验证码类
 * User: zhoumuhao
 * Date: 2018/10/1
 * Time: 19:06
 */
class Vcode
{
    private $width;  //宽
    private $height; //高
    private $num; //个数
    private $code;  //验证码
    private $codestring = "3456789abcdefghijkmnpqrstuvwxyABCDEFGHIJKLMNPQRSTUVWXY";  //组成验证码的随机字符串
    private $img; //验证码的资源
    private $dotnum='100'; //设置干扰素点的个数
    private $linesnum='10'; //设置干扰素线条的个数

    /**
     * Vcode constructor.
     * @param $width int 验证码的宽度
     * @param $height 验证码的高度
     * @param $num  验证码的显示个数
     */
    public function __construct($width,$height,$num)
    {
        $this->width = $width;
        $this->height = $height;
        $this->num = $num;
        $this->code = $this->createcode(); //为了保持验证码的一致性
    }

    //获得验证码的字符，存于session便于匹配
    public function getcode()
    {
        return $this->code;
    }

    //web输出验证码
    public function outimg()
    {
        //创建背景（颜色，大小，边框）
        $this->createback();
        //画字（字体，大小，颜色）
        $this->outstring();
        //干扰元素（点，线条）
        $this->setdisturbcolor();
        //输出图像
        $this->printimg();
    }

    //生成验证码
    private function createcode()
    {
        $code="";
        for($i=0;$i<$this->num;$i++){
            $code .=$this->codestring{rand(0,strlen($this->codestring)-1)};
        }
        return $code;
    }

    //创建背景
    private function createback()
    {
        $this->img = imagecreatetruecolor ($this->width,$this->height);
        //背景颜色(随机)
        $bgcolor = imagecolorallocate($this->img,rand(225,255),rand(225,255),rand(225,255));
        //填充画布
        imagefill($this->img,0,0,$bgcolor);
        //设置边框颜色(黑色)
        $bordercolor = imagecolorallocate($this->img,0,0,0);
        //画一个矩形 宽高减1 保证在画布内
        imagerectangle ($this->img ,0,0,$this->width-1,$this->height-1,$bordercolor);
    }

    //画字
    private function outstring()
    {
        for($i=0;$i<$this->num;$i++){
            //设置字体颜色
            $stringcolor = imagecolorallocate($this->img,rand(0,128),rand(0,128),rand(0,128));
            //字体大小
            $fontsize = rand(3,5);
            //设置字符水平位置
            $x = 3+($this->width/$this->num)*$i;
            //设置字符的垂直位置
            $y = rand(0,imagefontheight($fontsize)-5);
            //画出字符
            imagechar ($this->img,$fontsize,$x,$y,$this->code[$i] ,$stringcolor);
        }
    }

    //设置干扰元素
    private function setdisturbcolor()
    {
        //设置点
        for($i=0;$i<$this->dotnum;$i++){
            //设置点的颜色
            $dotcolor = imagecolorallocate($this->img,rand(0,255),rand(0,255),rand(0,255));
            imagesetpixel ($this->img ,rand(1,$this->width-2),rand(1,$this->height-2) ,$dotcolor);
        }
        //设置线条
        for($i=0;$i<$this->linesnum;$i++){
            //设置线条的颜色
            $linecolor = imagecolorallocate($this->img,rand(100,255),rand(128,255),rand(130,255));
            //圆弧
            imagearc ($this->img,rand(-10,$this->width+10),rand(-10,$this->height+10),rand(30,300),rand(30,300),55 ,44,$linecolor);
        }
    }

    //输出头像
    private function printimg()
    {
        // 处理输出(自动检测 GD 支持的图像类型来写出移植性更好的 PHP 程序)
        if(imagetypes() & IMG_GIF)
        {
            // 针对 GIF
            header('Content-Type: image/gif');
            imagegif($this->img);
        } elseif(function_exists('imagejpeg')) {
            // 针对 JPEG
            header('Content-Type: image/jpeg');
            imagegif($this->img);
        } elseif(imagetypes() & IMG_PNG) {
            // 针对 PNG
            header('Content-Type: image/png');
            imagepng($this->img);
        } else {
            imagedestroy($this->img);
            die('No image support in this PHP server');
        }
    }

    //销毁资源
    public function __destruct()
    {
        imagedestroy ($this->img);
    }
}